home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_asm / nnansi3 / nnansi_f.asm < prev    next >
Assembly Source File  |  1989-09-25  |  21KB  |  823 lines

  1.     page    60, 132
  2. ;----- nnansi_f.asm ---------------------------------------------
  3. ; The ANSI control subroutines.
  4. ; (C) 1986 Daniel Kegel, Pasadena, CA
  5. ; May be distributed for educational and personal use only
  6. ; Each routine is called with the following register usage:
  7. ;  AX = max(1, value of first parameter)
  8. ;  Z flag is set if first parameter is zero.
  9. ;  CX = number of paramters
  10. ;  SI = offset of second parameter from CS
  11. ;  DS = CS
  12. ;  ES:DI points to the current location on the memory-mapped screen.
  13. ;  DX is number of characters remaining on the current screen line.
  14. ; The control routine is free to trash AX, BX, CX, SI, and DS.
  15. ; It must preserve ES, and can alter DX and DI if it wants to move the
  16. ; cursor.
  17. ;
  18. ; Revisions:
  19. ;  19 Aug 85: Fixed horrible bug in insert/delete line.
  20. ;  26 Aug 85: Fixed simple limit-to-one-too-few-lines bug in ins/del line;
  21. ;  anyway, it inserts 24 lines when on line 2 now.  Whether it's fixed...
  22. ;  4 Sept 85: Fixed bug created on 26 Aug 85; when limiting ins/del line
  23. ;  count, we are clearing, not scrolling; fixed BIOS call to reflect this.
  24. ;  30 Jan 86: Added EGA cursor patch
  25. ;  31 Jan 86: Disabled insert/delete char in graphics modes
  26. ;          Implemented keyboard redefinition reset
  27. ;  1 Feb 86: added video_mode and max_x test after mode set
  28. ;  8 Jan 89:  Slight changes for compilation options
  29. ;----------------------------------------------------------------
  30.  
  31.     include nnansi_d.asm
  32.  
  33.     ; To nnansi_p.asm
  34.     public    ansi_fn_table
  35.  
  36.     ; From nnansi.asm
  37.  
  38. port_6845    equ    3d4h
  39.  
  40.     extrn    cur_coords:word, saved_coords:word
  41.     extrn    cur_x:byte, max_x:byte
  42.     extrn    cur_y:byte, max_y:byte
  43.     extrn    cur_attrib:byte, wrap_flag:byte
  44.     extrn    xy_to_regs:near
  45.     extrn    get_blank_attrib:near
  46. if out_trans
  47.     extrn    xlate_tab_ptr:word
  48. endif
  49.     extrn    cpr_esc:byte, cprseq:word
  50.     extrn    video_mode:byte
  51. if key_redef
  52.     extrn    lookup:near
  53. endif
  54.     extrn    gmode_flag:byte
  55.     extrn    gcursor:byte
  56.     extrn    recurse:byte
  57.  
  58.     ; from nnansi_p.asm
  59.     extrn    param_buffer:word    ; used in keyboard programming
  60.     extrn    param_end:word
  61. if key_redef
  62.     extrn    redef_end:word
  63. endif
  64.  
  65. keybuf    struc                ; used in making cpr sequence
  66. len    dw    ?
  67. adr    dw    ?
  68. keybuf    ends
  69.  
  70.  
  71. ABS40    segment at 40h
  72.     org    1ah
  73. buffer_head    dw    ?    ; Used in 'flush input buffer' dos call.
  74. buffer_tail    dw    ?
  75.  
  76.     org    49h
  77. crt_mode    db    ?
  78. crt_cols    dw    ?
  79. crt_len        dw    ?
  80. crt_start    dw    ?
  81. cursor_posn    dw    8 dup (?)
  82. cursor_mode    dw    ?
  83. active_page    db    ?
  84. addr_6845    dw    ?
  85. crt_mode_set    db    ?
  86. crt_palette    db    ?
  87.  
  88. ABS40    ends
  89.  
  90. code    segment byte public 'CODE'
  91.     assume cs:code, ds:code
  92.  
  93. ;----- byteout ---------------------------------------------------
  94. ; Converts al to a decimal ASCII string (in 0..99),
  95. ; stores it at ES:DI++.     Returns DI pointing at byte after last digit.
  96. ; Destroys DL.
  97.  
  98. byteout proc    near
  99.     cmp    al, 100        ; check for >99 case TAA mod
  100.     jb    goodbyteout
  101.     push    ax
  102.     mov    al, '1'        ; assume value <200!
  103.     stosb
  104.     pop    ax
  105.     sub    ax, 100
  106. goodbyteout:
  107.     aam
  108.     add    ax, 3030h
  109.     xchg    ah, al
  110.     stosb
  111.     xchg    ah, al
  112.     stosb
  113.     ret
  114. byteout endp
  115.  
  116. ;----- ansi_fn_table -----------------------------------
  117. ; Table of offsets of terminal control subroutines in order of
  118. ; the character that invokes them, @..Z, a..z.    Exactly 53 entries.
  119. ; All the subroutines are defined below in this module.
  120. ansi_fn_table    label    word
  121.     dw    ic,  cup, cdn, cfw, cbk        ; @, A, B, C, D
  122.     dw    nul, nul, nul, hvp, nul        ; E, F, G, H, I
  123.     dw    eid, eil, il,  d_l, nul        ; J, K, L, M, N
  124.     dw    nul, dc,  nul, nul, nul        ; O, P, Q, R, S
  125.     dw    nul, nul, nul, nul, nul        ; T, U, V, W, X
  126.     dw    nul, nul            ; Y, Z
  127.     dw    nul, nul, nul, nul, nul        ; a, b, c, d, e
  128.     dw    hvp, nul, sm,  nul, nul        ; f, g, h, i, j
  129.     dw    nul, rm,  sgr, dsr, nul        ; k, l, m, n, o
  130. if key_redef
  131.     dw    key, nul, nul, scp, nul        ; p, q, r, s, t
  132. else
  133.     dw    nul, nul, nul, scp, nul        ; p, q, r, s, t
  134. endif
  135. if out_trans
  136.     dw    rcp, nul, nul, nul, xoc        ; u, v, w, x, y
  137. else
  138.     dw    rcp, nul, nul, nul, nul        ; u, v, w, x, y
  139. endif
  140.     dw    nul                ; z
  141.  
  142. ansi_functions    proc    near        ; set return type to NEAR
  143.  
  144. ;----- nul ---------------------------------------------
  145. ; No-action ansi sequence; called when unknown command given.
  146. nul:    ret
  147.  
  148. ;----- Cursor Motion -----------------------------------------------
  149.  
  150. ;-- cursor to y,x
  151. hvp:    or    al, al        ; First parameter is desired Y coordinate.
  152.     jz    hvp_yok
  153.     dec    ax        ; Convert to zero-based coordinates.
  154. hvp_yok:mov    cur_y, al
  155.     ; Get second parameter, if it is there, and set X with it.
  156.     xor    ax, ax
  157.     cmp    cx, 2        ; was there a second parameter?
  158.     jb    hvp_xok
  159.     lodsb            ; yes.
  160.     or    al, al
  161.     jz    hvp_xok
  162.     dec    ax        ; convert to zero-based coordinates.
  163. hvp_xok:mov    cur_x, al
  164.  
  165.     ; Clip to maximum coordinates.
  166. hvp_set:
  167.     mov    ax, cur_coords        ; al = x, ah = y
  168.     cmp    al, max_x
  169.     jbe    hvp_sxok
  170.         mov    al, max_x
  171.         mov    cur_x, al
  172. hvp_sxok:
  173.     cmp    ah, max_y
  174.     jbe    hvp_syok
  175.         mov    al, max_y
  176.         mov    cur_y, al
  177. hvp_syok:
  178.     ; Set values of DX and DI accordingly.
  179.     call    xy_to_regs
  180.     ret
  181.  
  182. ;-- cursor forward --
  183. cfw:    add    cur_x, al
  184.     jmp    hvp_set
  185.  
  186. ;-- cursor back -----
  187. cbk:    sub    cur_x, al
  188.     jae    cbk_ok
  189.         mov    cur_x, 0
  190. cbk_ok: jmp    hvp_set
  191.  
  192. ;-- cursor down -----
  193. cdn:    add    cur_y, al
  194.     jmp    hvp_set
  195.  
  196. ;-- cursor up -------
  197. cup:    sub    cur_y, al
  198.     jae    cup_ok
  199.         mov    cur_y, 0
  200. cup_ok: jmp    hvp_set
  201.  
  202. ;-- save cursor position --------------------------------------
  203. scp:    mov    ax, cur_coords
  204.     mov    saved_coords, ax
  205.     ret
  206.  
  207. ;-- restore cursor position -----------------------------------
  208. rcp:    mov    ax, saved_coords
  209.     mov    cur_coords, ax
  210.     jmp    hvp_set        ; Clip in case we have switched video modes.
  211.  
  212. ;-- set graphics rendition ------------------------------------
  213. ; Modifies the color in which new characters are written.
  214.  
  215. if more_sgr
  216. rev_flag    db    0    ; non-zero if in reverse video
  217. endif
  218. sgr:    dec    si        ; get back pointer to first parameter
  219.     or    cx, cx        ; Did he give any parameters?
  220.     jnz    sgr_loop
  221.         mov    byte ptr [si], 0    ; no parameters, so fake
  222.         inc    cx            ; one with the default value.
  223.     ; For each parameter
  224. sgr_loop:
  225.         lodsb                ; al = next parameter
  226.         ; Search color table
  227.         push    cx
  228. if more_sgr
  229.         cmp    al, 7            ; reverse video?
  230.         jz    sgr_rev
  231.         cmp    al, 27            ; unreverse video?
  232.         jz    sgr_unrev
  233.         cmp    al, 0            ; not reset?
  234.         jnz    sgr_continue
  235.         mov    rev_flag, 0
  236. sgr_continue:
  237. endif
  238.         mov    cx, colors
  239.         mov    bx, offset color_table-3
  240. sgr_search:
  241.             add    bx, 3
  242.             cmp    al, byte ptr [bx]
  243.             loopnz    sgr_search    ; until match found or done
  244.         jnz    sgr_loopx
  245.  
  246.         ; If parameter named a known color, set the current
  247.         ; color variable.
  248. if more_sgr
  249.         cmp    rev_flag,0        ; not reverse video?
  250.         jz    sgr_1
  251.         call    sgr_flip        ; temporary unreverse
  252. sgr_1:
  253. endif
  254.         mov    ax, [bx+1]
  255.         and    cur_attrib, al
  256.         or    cur_attrib, ah
  257. if more_sgr
  258.         cmp    rev_flag,0        ; not reverse video?
  259.         jz    sgr_2
  260.         call    sgr_flip        ; reverse it 
  261. sgr_2:
  262. endif
  263. sgr_loopx:
  264.         pop    cx
  265.         loop    sgr_loop        ; until no more parameters.
  266.     ret
  267.  
  268. if more_sgr
  269. sgr_rev:    
  270.         cmp    rev_flag,0        ; already reverse?
  271.         jnz    sgr_loopx
  272.         inc    rev_flag        ; reverse things
  273.         call    sgr_flip
  274.         jmp    sgr_loopx
  275.  
  276. sgr_unrev:    cmp    rev_flag,0        ; already not-reverse?
  277.         jz    sgr_loopx
  278.         dec    rev_flag        ; unreverse things
  279.         call    sgr_flip
  280.         jmp    sgr_loopx
  281.  
  282. sgr_flip:
  283.         push    ax
  284.         mov    al, cur_attrib        ; get attribute
  285.         mov    ah, al            ; copy it
  286. if is_8088
  287.         ror    ah,1            ; swap nibbles
  288.         ror    ah,1
  289.         ror    ah,1
  290.         ror    ah,1
  291. else
  292.         ror    ah,4
  293. endif
  294.         and    ah,77h            ; get only color bits
  295.         and    al,88h            ; get only intens/blink bits
  296.         or    al,ah            ; join them
  297.         mov    cur_attrib,al        ; save flipped value
  298.         pop    ax
  299.         ret
  300. endif
  301.  
  302. ;-- erase in line ----------------------------------------
  303. ; Uses BIOS to scroll away a one-line rectangle
  304. eil:    push    dx
  305.     mov    cx, cur_coords
  306.     mov    dh, ch
  307.     jmp    short scrollem
  308.  
  309. ;-- erase in display -------------------------------------
  310. ; Uses BIOS to scroll away all of display
  311. eid:    
  312. if erase_extension
  313.     jz    eid_toend    ; first parms=0 -- erase to end
  314.     or    cx,cx        ; no args?
  315.     jz    eid_toend    ;  then erase to end
  316.     cmp    al, 1        ; erase to beginning?
  317.     jz    eid_tostart
  318. endif
  319.     cmp    al, 2
  320.     jnz    eid_ignore    ; param must be two
  321.     if    cls_homes_too
  322.         mov    cur_coords, 0
  323.         call    xy_to_regs
  324.         if fast
  325.         xor    di, di    ; offset will be zero after clearing
  326.         endif
  327.     endif
  328. if    fast
  329.     cmp    gmode_flag, 0
  330.     jnz    dont_say_it
  331.     mov    recurse, 0    ; say not recursive so display resets
  332. dont_say_it:
  333. endif
  334.     push    dx
  335.     xor    cx, cx
  336.     mov    dh, max_y
  337. scrollem:
  338.     call    get_blank_attrib
  339.     mov    bh, ah
  340.     mov    dl, max_x
  341. eid_process:
  342.     mov    ax, 600h
  343.     int    10h
  344. if fast
  345.     mov    recurse, 1    ; we are recursive
  346. endif
  347. eid_done:
  348.     pop    dx
  349. eid_ignore:
  350.     ret
  351.  
  352. if erase_extension
  353. eid_toend:    ; erase following lines then go back and erase in line
  354.     push    dx
  355.     call    get_blank_attrib
  356.     mov    bh,ah
  357.     mov    ax, 600h
  358.     mov    dh, max_y
  359.     mov    dl, max_x
  360.     mov    ch, cur_y
  361.     inc    ch
  362.     cmp    ch, dh            ; don't erase if no following
  363.     ja    eid_nopost
  364.     xor    cl,cl
  365.     int    10h
  366. eid_nopost:
  367.     mov    cx, cur_coords
  368.     mov    dh, ch
  369.     jmp    short scrollem
  370.  
  371.  
  372. eid_tostart:    ; erase preceeding lines then go back and erase in line
  373.     push    dx
  374.     call    get_blank_attrib
  375.     mov    bh,ah
  376.     mov    dh, cur_y
  377.     dec    dh
  378.     js    eid_nopre        ; don't erase if no preceeding
  379.     mov    ax,600h
  380.     xor    cx,cx
  381.     mov    dl, max_x
  382.     int    10h
  383. eid_nopre:
  384.     mov    dx, cur_coords
  385.     dec    dl
  386.     js    eid_done
  387.     mov    ch, dh
  388.     xor    cl, cl
  389.     jmp    eid_process
  390. endif
  391.     
  392. ;-- device status report --------------------------------
  393. ; Stuffs an escape, a left bracket, current Y, semicolon, current X,
  394. ; a capital R, and a carriage return into input stream.
  395. ; The coordinates are 1 to 3 decimal digits each.
  396.  
  397. dsr:    push    di
  398.     push    dx
  399.     push    es
  400.     mov    ax, cs
  401.     mov    es, ax
  402.     std            ; Store string in reversed order for fun
  403.     mov    di, offset cpr_esc - 2
  404.     mov    al, cur_y
  405.     inc    al        ; convert to one-based coords
  406.     call    byteout        ; row
  407.     mov    al, ';'        ; ;
  408.     stosb
  409.     mov    al, cur_x
  410.     inc    al        ; convert to one-based coords
  411.     call    byteout        ; column
  412.     mov    al, 'R'        ; R ANSI function 'Cursor Position Report'
  413.     stosb
  414.     mov    al, 13
  415.     mov    word ptr cprseq.adr, di ; save pointer to last char in string
  416.     stosb                ; send a carriage return, too
  417.     mov    ax, offset cpr_esc
  418.     sub    ax, di            ; ax is # of characters in string
  419.     mov    word ptr cprseq.len, ax ; pass info to the getchar routine
  420.     cld
  421.     pop    es
  422.     pop    dx
  423.     pop    di
  424.     ret
  425. if key_redef
  426. ;-- keyboard reassignment -------------------------------
  427. ; Key reassignment buffer is between param_end and redef_end+2, exclusive.
  428. ; When it shrinks or grows, param_end is moved.
  429. ; Format of an entry is as follows:
  430. ;   highest address -> length:word (may be 0)
  431. ;               key to replace:word     (either hi or low byte is zero)
  432. ;               .
  433. ;               .    new key value, "length" bytes long
  434. ;               .
  435. ;   lowest address  -> next entry, or free space.
  436. ; If no arguments are given, keyboard is reset to default condition.
  437. ; Otherwise, first parameter (or first two, if first is zero) defines
  438. ; the key whose value is to be changed, and the following parameters
  439. ; define the key's new, possibly zero-length, value.
  440.  
  441. key:
  442.     ; Is this a reset?
  443.     or    cx, cx
  444.     jz    key_init
  445.     ; Get the first (or first two) parameters
  446.     cld
  447.     dec    si    ; point to first param
  448.     dec    cx    ; Assume it's a fn key, get two params
  449.     dec    cx
  450.     lodsw
  451.     or    al, al    ; Is it a function key?
  452.     jz    key_fnkey
  453.         ; It's not a function key- put second param back
  454.         inc    cx
  455.         dec    si
  456. key_fnkey:
  457.     ; Key to redefine now in AX.  If it's already redefined,
  458.     ; lookup will set Z, point SI to redef string, set CX to its length.
  459.     push    di
  460.     push    es
  461.     push    cx
  462.     push    si
  463.  
  464.     std            ; moving up, must move from top down
  465.     push    ds
  466.     pop    es        ; string move must have ES=DS
  467.     call    lookup        ; rets Z if redefined...
  468.     jnz    key_newkey
  469.     ; It's already defined.     Erase its old definition- i.e., move
  470.     ; region param_end+1..SI-1 upwards CX+4 bytes, add CX+4 to param_end.
  471.     add    cx, 4
  472.     mov    bp, param_end    ; save old value in bp...
  473.     add    param_end, cx
  474.     dec    si        ; start at (SI-1)
  475.     mov    di, si
  476.     add    di, cx        ; move to (start + CX+4)
  477.     mov    cx, si
  478.     sub    cx, bp        ; length of region old_param_end+1..start
  479.     rep    movsb
  480. key_newkey:
  481.     ; Key not redefined.  See if there's enough room to redefine it.
  482.     pop    si        ; get back pointer to redef string
  483.     pop    cx        ; get back number of bytes in redef string
  484.     mov    di, param_end    ; hi byte of new redef record, hi byte of len
  485.     sub    di, 4        ; hi byte of new data field
  486.     mov    bx, di
  487.     sub    bx, cx        ; hi byte of remaining buffer space
  488.     sub    bx, 16        ; better be at least 16 bytes room
  489.     cmp    bx, param_buffer
  490.     jb    key_popem    ; nope- forget it.
  491.     ; Nothing in the way now!
  492.     mov    [di+3], cx    ; save length field
  493.     mov    [di+1], ax    ; save name field
  494.     jcxz    key_nullstring
  495. key_saveloop:            ; save data field
  496.     movsb
  497.     add    si, 2        ; input string ascending, output descending
  498.     loop    key_saveloop
  499. key_nullstring:
  500.     mov    param_end, di    ; save adr of new hi byte of free area
  501. key_popem:
  502.     pop    es
  503.     pop    di
  504.  
  505. key_exit:
  506.     cld
  507.     ret
  508.  
  509. key_init:
  510.     ; Build the default redefinition table:
  511.     ;    control-printscreen -> control-P
  512.     push    es
  513.     push    ds
  514.     pop    es
  515.     std
  516.     mov    di, redef_end
  517.     mov    ax, 1
  518.     stosw
  519.     mov    ax, 7200h    ; control-printscreen
  520.     stosw
  521.     mov    al, 16        ; control P
  522.     stosb
  523.     mov    param_end, di    ; save new bottom of redef table
  524.     pop    es
  525.     jmp    key_exit
  526. endif
  527.  
  528.  
  529. ;---- Delete/Insert Lines -------------------------------
  530. ; AL is number of lines to delete/insert.
  531. ; Preserves DX, DI; does not move cursor.
  532.  
  533. d_l:    ; Delete lines.
  534.     mov    ah, 6            ; BIOS: scroll up
  535.     jmp    short il_open
  536.  
  537. il:    ; Insert lines.
  538.     mov    ah, 7            ; BIOS: scroll down
  539.  
  540. il_open:
  541.     ; Whether inserting or deleting, limit him to (max_y - cur_y) lines;
  542.     ; if above that, we're just clearing; set AL=0 so BIOS doesn't burp.
  543.     mov    bh, max_y
  544.     sub    bh, cur_y
  545.     cmp    al, bh
  546.     jbe    il_ok            ; DRK 9/4...
  547.         mov    al, 0        ; he tried to move too far
  548. il_ok:
  549.     push    ax
  550.     call    get_blank_attrib
  551.     mov    bh, ah            ; color to use on new blank areas
  552.     pop    ax            ; AL is number of lines to scroll.
  553.  
  554.     mov    cl, 0            ; upper-left-x of data to scroll
  555.     mov    ch, cur_y        ; upper-left-y of data to scroll
  556.     push    dx
  557.     mov    dl, max_x        ; lower-rite-x
  558.     mov    dh, max_y        ; lower-rite-y (zero based)
  559.     int    10h            ; call BIOS to scroll a rectangle.
  560.     pop    dx
  561.     ret                ; done.
  562.  
  563. ;-- Insert / Delete Characters ----------------------------
  564. ; AL is number of characters to insert or delete.
  565. ; Preserves DX, DI; does not move cursor.
  566.  
  567. ic:    mov    ch, 1            ; 1 => swap dest & source below
  568.     jmp    short dc_ch
  569.  
  570. dc:    mov    ch, 0
  571.  
  572. dc_ch:
  573.     cmp    cs:gmode_flag,0
  574.     jnz    dc_ret            ; | if in graphics mode, ignore.
  575.  
  576.  
  577.     ; AL = number of chars to ins or del (guarenteed nonzero).
  578.     ; Limit him to # of chars left on line.
  579.     cmp    al, dl
  580.     jbe    dc_cok
  581.         mov    al, dl
  582. dc_cok:
  583.     push    di            ; DI is current address of cursor
  584.     xchg    ax, cx            ; CX gets # of chars to ins/del
  585.     mov    bp, cx            ; BP gets # of columns to clear.
  586.  
  587.     ; Set up source = destination + cx*2, count = dx - cx
  588.     mov    ch, 0            ; make it a word
  589.     mov    si, di
  590.     add    si, cx
  591.     add    si, cx
  592.     neg    cl
  593.     add    cl, dl
  594.     mov    ch, 0            ; CX = # of words to transfer
  595.     cld                ; REP increments si & di
  596.  
  597.     ; If this is an insert, then flip transfer around in both ways.
  598.     test    ah, 1
  599.     jz    dc_noswap
  600.         xchg    di, si        ; source <-> dest
  601.         std            ; up <-> down
  602.         mov    ax, cx        ; make move over same range
  603.         dec    ax
  604.         add    ax, ax        ; AX=dist from 1st to last byte.
  605.         add    di, ax        ; Start transfer at high end of block
  606.         add    si, ax        ;  instead of low end.
  607. dc_noswap:
  608.     ; Move those characters.
  609.     push    es
  610.     pop    ds
  611.     rep    movsw
  612.     mov    cx, bp
  613.     ; Figure out what color to make the new blanks.
  614.     call    get_blank_attrib
  615.     mov    al, ' '
  616.     ; Blank out vacated region.
  617.     rep    stosw
  618.  
  619.     ; All done.
  620.     cld                ; restore normal REP state and
  621.     pop    di            ;  cursor address.
  622. dc_ret: ret
  623.  
  624.  
  625. ;---- set / reset mode ---------------------------------------
  626. ; Sets graphics/text mode; also sets/resets "no wrap at eol" mode.
  627. ; also set/reset graphic cursor mode
  628. sm:    mov    cl, 0ffh    ; set
  629. sm_rs:
  630.     ; Is it "wrap at eol" ?
  631.     cmp    al, 7
  632.     jnz    sm_notwrap
  633.         mov    wrap_flag, cl    ; true = wrap at EOL
  634.         ret
  635. sm_notwrap:
  636.     ; Is it set/reset graphic cursor mode?
  637.     cmp    al,99
  638.     jnz    sm_notgcursor
  639.         mov    gcursor, cl
  640. sm_done:    ret
  641. sm_notgcursor:
  642.     ; Is it "set highest number of screen lines available"?
  643.     cmp    al, 43
  644.     jnz    sm_not43
  645.         ; Only valid for the Enhanced Graphics Adaptor on
  646.         ; a monochrome display or an enhanced color display.
  647.  
  648.         ; 43 line mode only allowed in text modes, for now.
  649.         cmp    cs:gmode_flag,0
  650.         jnz    sm_done
  651.  
  652.         mov    ah, 0            ; "Set video mode"
  653.         mov    al, video_mode        ; Re-init current mode
  654.         int    10h
  655.  
  656.         mov    ax,1112h        ; Load 8x8 font
  657.         mov    bl,0            ; (instead of 8x14)
  658.         int    10h
  659.  
  660.         mov    ax, 1200h        ; Load new printscreen
  661.         mov    bl, 20h
  662.         int    10h
  663.  
  664.         mov    ah,1
  665.         mov    cx,0707h        ; (Load cursor scan lines)
  666.         int    10h
  667.         ; | Patch; this gotten by painful observation of
  668.         ; | IBM's professional editor.    I think there's a
  669.         ; | documented bug in Video Bios's "load cursor scan line"
  670.         ; | call; try looking in latter 1985 PC Tech Journal.
  671.         mov    dx, port_6845        ; '6845' command reg
  672.         mov    al, 10
  673.         out    dx, al
  674.         jmp    $+2
  675.         inc    dx
  676.         mov    al, 7
  677.         out    dx, al            ; set cursor start line
  678.         ; Assume that gets us 43 lines.
  679.         mov    max_y, 42
  680.         jmp    short sm_home
  681.  
  682. sm_not43:    cmp    al,50            ; not 50 line (VGA)
  683.         jnz    sm_video
  684.         cmp    cs:gmode_flag,0        ; must not be graphic mode
  685.         jnz    sm_done
  686.  
  687.         mov    ax, 1202h        ; select 400 scan lines
  688.         mov    bl,30h
  689.         int    10h
  690.         
  691.         mov    ax, 3h            ; select mode 3
  692.         int    10h
  693.         
  694.         mov    ax, 1112h        ; 8x8 character set
  695.         mov    bl,0
  696.         int    10h
  697.  
  698.         mov    ax, 1200h        ; Load new printscreen
  699.         mov    bl, 20h
  700.         int    10h
  701.         jmp    SHORT sm_home
  702. sm_video:
  703.     ; It must be a video mode.  Call BIOS.
  704.     ; Save graphics mode flag
  705.     extrn    set_gmode:near
  706.     call    set_gmode    ; mode is in AL
  707.     
  708.     mov    ah, 0        ; "set video mode"
  709.     int    10h
  710.     ; Assume that gets us 25 lines.
  711.     mov    max_y, 24
  712. sm_home:
  713.     ; Read the BIOS buffer address/cursor position variables.
  714.     mov    ax, ABS40
  715.     push    ds
  716.     mov    ds, ax
  717.     assume    ds:ABS40
  718.     ; Find current video mode and screen size.
  719.     mov    ax,word ptr crt_mode    ; al = crt mode; ah = # of columns
  720.     pop    ds
  721.     mov    video_mode, al
  722.     dec    ah            ; ah = max column
  723.     mov    max_x, ah
  724.  
  725.     ; Since cursor may end up in illegal position, it's best to
  726.     ; just go home after switching video modes.
  727.     mov    cur_coords, 0
  728.     call    xy_to_regs
  729.     ret
  730.  
  731. rm:    mov    cl, 0        ; reset
  732.     jmp    sm_rs
  733.  
  734. if out_trans
  735. ;------- Output Character Translation ----------------------
  736. ; A decidedly nonstandard function, possibly useful for editing files
  737. ; intended to be printed by daisywheel printers with strange wheels.
  738. ; (The letter 'y' was chosen to conflict with the VT100 self-test command.)
  739. ; Usage: ESC [ #1;#2 y
  740. ; where #1 is the character to redefine
  741. ;    #2 is the new display value
  742. ; If only ESC [ #1 y is sent, character #1 is reset to its default value.
  743. ; If only ESC [ y is sent, the entire table is reset to the default value.
  744. ; (If only ESC [ #1; y is sent, character #1 is set to zero... sigh.)
  745.  
  746. xoc:    ; Xlate output character
  747.     mov    bx, xlate_tab_ptr
  748.     jcxz    xoc_reset    ; if no parameters, reset table to 1:1
  749.     dec    si        ; point to first parameter
  750.     lodsw            ; first parameter to AL, second to AH
  751.     dec    cx        ; is parameter count 1?
  752.     jnz    xoc_bothparams
  753.         mov    ah, al    ; if only one param, reset that char.
  754. xoc_bothparams:
  755.     add    bl, al
  756.     adc    bh, 0        ; bx points to entry for char AL
  757.     mov    byte ptr [bx], ah    ; change that entry
  758. xoc_done:
  759.     ret
  760.  
  761. xoc_reset:
  762.     ; Fill table with default values- i.e. 0, 1, 2, ... 255.
  763.     xor    ax, ax
  764. xoc_loop:
  765.     mov    byte ptr [bx], al
  766.     inc    bx
  767.     inc    al
  768.     jnz    xoc_loop
  769.     jmp    xoc_done
  770. endif
  771.  
  772. ansi_functions    endp    ; end dummy procedure block
  773.  
  774.  
  775.  
  776. ;-------- Color table -----------------------------------------
  777. ; Used in "set graphics rendition"
  778. if more_sgr
  779. colors    equ    25            ; number of colors in table
  780. else
  781. colors    equ    22            ; number of colors in table
  782. endif
  783. color_table:
  784.     db    0, 000h,07h        ; all attribs off; normal.
  785.     db    1, 0ffh,08h        ; bold
  786. if more_sgr
  787.     db    2, 0f7h,00h        ; dim (not bold)
  788. endif
  789.     db    4, 0f8h,01h        ; underline (forces blue foreground)
  790.     db    5, 0ffh,80h        ; blink
  791. ife more_sgr
  792.     db    7, 0f8h,70h        ; reverse
  793. endif
  794.     db    8, 088h,00h        ; invisible
  795.  
  796. if more_sgr
  797.     db    22,0f7h,00h        ; un-bold, un-dim
  798.     db    24,0f8h,7h        ; un-underline (forces white foreground)
  799.     db    25,07fh,0h        ; un-blink
  800. endif
  801.     db    30,0f8h,00h        ; black foreground
  802.     db    31,0f8h,04h        ; red
  803.     db    32,0f8h,02h        ; green
  804.     db    33,0f8h,06h        ; yellow
  805.     db    34,0f8h,01h        ; blue
  806.     db    35,0f8h,05h        ; magenta
  807.     db    36,0f8h,03h        ; cyan
  808.     db    37,0f8h,07h        ; white
  809.  
  810.     db    40,08fh,00h        ; black background
  811.     db    41,08fh,40h        ; red
  812.     db    42,08fh,20h        ; green
  813.     db    43,08fh,60h        ; yellow
  814.     db    44,08fh,10h        ; blue
  815.     db    45,08fh,50h        ; magenta
  816.     db    46,08fh,30h        ; cyan
  817.     db    47,08fh,70h        ; white
  818.  
  819.  
  820. code    ends
  821.     end                ; of nnansi_f.asm
  822.  
  823.